﻿#ifndef __SS_TWO_DIMENSIONAL_ARRAY_H__
#define __SS_TWO_DIMENSIONAL_ARRAY_H__
#include "ssArray.h"
#include "ssNumArray.h"

namespace StarSeeker
{

template <typename T, typename A>
class ssTwoDimensionalArray
{
public:
	ssTwoDimensionalArray(void)
	{
		m_row = 0;
		m_column = 0;
		m_count = 0;
	}
	ssTwoDimensionalArray(const ssTwoDimensionalArray& tda)
		:m_array(tda.m_array)
	{
		m_row = tda.m_row;
		m_column = tda.m_column;
		m_count = tda.m_count;
	}
	virtual ~ssTwoDimensionalArray(void)
	{
		Clear();
	}
	//行数 列数 创建一个数组
	bool Init(ulint row, ulint colum)
	{
		if (!m_array.Memory())
		{
			m_row = row;
			m_column = colum;
			m_count = m_row*m_column;
			return m_array.Init(m_count);
		}
		return false;
	}
	//释放内存
	void Clear()
	{
		m_array.Clear();
		m_row = 0;
		m_column = 0;
		m_count = 0;
	}
	//清空
	void Empty()
	{
		m_array.Empty();
	}
	//返回总数
	ulint Count() const
	{
		return m_count;
	}
	//按二维数组访问
	T * At(ulint row, ulint colum)
	{
		if (row<m_row && colum<m_column)
		{
			return m_array.At(row*m_column+colum);
		}
		return 0;
	}
	//按一维数组访问
	T * At(ulint offset)
	{
		if (offset<m_count)
		{
			return m_array.At(offset);
		}
		return 0;
	}
	//按二维数组访问
	T & operator () (ulint row, ulint colum) const
	{
		return m_array[row*m_column + colum];
	}
	//按一维数组访问
	T & operator [] (ulint offset) const
	{
		return m_array[offset];
	}
	//一维转二维行
	ulint SwitchRow(ulint offset) const
	{
		return offset/m_column;
	}
	//一维转二维列
	ulint SwitchColumn(ulint offset) const
	{
		return offset%m_column;
	}
	//二维转一维
	ulint SwitchOneDimensional(ulint row, ulint colum) const
	{
		return row * m_column + colum;
	}
	ulint Row() const
	{
		return m_row;
	}
	ulint Column() const
	{
		return m_column;
	}
private:
	A			m_array;
	ulint			m_row;		//行数
	ulint			m_column;	//列数
	ulint			m_count;	//总数
};

template <typename T>
class ssTDArray : public ssTwoDimensionalArray<T, ssArray<T,0> >
{
public:
	ssTDArray() {}
	ssTDArray(const ssTDArray& tda) :ssTwoDimensionalArray<T, ssArray<T,0> >(tda) {}
};

template <typename T>
class ssNumTDArray : public ssTwoDimensionalArray<T, ssNumArray<T, 0> >
{
public:
	ssNumTDArray() {}
	ssNumTDArray(const ssNumTDArray& tda) :ssTwoDimensionalArray<T, ssNumArray<T, 0> >(tda) {}
};

}
#endif
